package com.zboot.zbootadmin.project.gen.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import com.zboot.zbootadmin.common.annotation.DelCatalog;
import com.zboot.zbootadmin.common.annotation.Log;
import com.zboot.zbootadmin.common.constant.HttpStatus;
import com.zboot.zbootadmin.common.domain.ResponseData;
import com.zboot.zbootadmin.common.utils.UUID.UUID;
import com.zboot.zbootadmin.project.gen.service.GenService;
import com.zboot.zbootadmin.project.gen.service.TableService;
import com.zboot.zbootadmin.project.gen.vo.TablesVo;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @Author: zyt
 * @Description:代码生成
 * @Date: Created in 11:35 2020/6/26
 */
@RequestMapping("/tool")
@RestController
public class GenerateController {

    @Autowired
    private TableService tableService;

    @Autowired
    private GenService genService;

    @Log("获取数据库表")
    @PreAuthorize("@zboot.hasPermi('tool:code:list')")
    @PostMapping("/showAllTables")
    public ResponseData showAllTables(@RequestBody TablesVo tablesVo) {
        JSONArray jsonArray = new JSONArray();
        tableService.showAllTables(tablesVo).stream().forEach(data->jsonArray.add(data));
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("result",jsonArray);
        jsonObject.put("total",tableService.getTotal());
        return new ResponseData(HttpStatus.SUCCESS,jsonObject);
    }

    @Log("下载代码")
    @PreAuthorize("@zboot.hasPermi('tool:code:gen')")
    @PostMapping("/generateCode")
    @DelCatalog("deleteCatalog")
    public void generateCode(HttpServletResponse response, @RequestBody String ...tables) throws IOException {
        String downloadName = UUID.fastUUID()+".zip";
        //将文件进行打包下载
        try {
            OutputStream out = response.getOutputStream();
            genService.setConfig(this.getClass(),tables).execute();
            String oPath = System.getProperty("user.dir");
            byte[] data = createZip(oPath+"\\generateCode");//服务器存储地址
            response.reset();
            response.setHeader("Content-Disposition","attachment;fileName="+downloadName);
            response.addHeader("Content-Length", ""+data.length);
            response.setContentType("application/octet-stream;charset=UTF-8");
            IOUtils.write(data, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public byte[] createZip(String srcSource) throws Exception{
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream zip = new ZipOutputStream(outputStream);
        //将目标文件打包成zip导出
        File file = new File(srcSource);
        ergodic(zip,file,"");
        IOUtils.closeQuietly(zip);
        return outputStream.toByteArray();
    }

    public void ergodic(ZipOutputStream zip, File file, String dir) throws IOException {
        //如果当前的是文件夹，则进行进一步处理
        if (file.isDirectory()) {
            //得到文件列表信息
            File[] files = file.listFiles();
            //将文件夹添加到下一级打包目录
            zip.putNextEntry(new ZipEntry(dir + "/"));
            dir = dir.length() == 0 ? "" : dir + "/";
            //循环将文件夹中的文件打包
            for (int i = 0; i < files.length; i++) {
                ergodic(zip, files[i], dir + files[i].getName());         //递归处理
            }
        } else {   //当前的是文件，打包处理
            //文件输入流
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
            ZipEntry entry = new ZipEntry(dir);
            zip.putNextEntry(entry);
            zip.write(FileUtils.readFileToByteArray(file));
            IOUtils.closeQuietly(bis);
            zip.flush();
            zip.closeEntry();
        }
    }
}
